package io.renren.modules.app.service.impl;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import io.renren.common.utils.R;
import io.renren.modules.app.dao.ImGroupDao;
import io.renren.modules.app.dao.ImGroupUserDao;
import io.renren.modules.app.dao.UserDao;
import io.renren.modules.app.entity.*;
import io.renren.modules.app.service.ImGroupService;
import io.renren.modules.app.tio.TioServerConfig;
import io.renren.modules.app.tio.WsOnlineContext;
import io.renren.modules.app.utils.ChatUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import io.renren.common.utils.PageUtils;
import io.renren.common.utils.Query;
import org.springframework.transaction.annotation.Transactional;
import org.tio.core.ChannelContext;
import org.tio.core.Tio;
import org.tio.websocket.common.WsResponse;


@Service("imGroupService")
public class ImGroupServiceImpl extends ServiceImpl<ImGroupDao, ImGroupEntity> implements ImGroupService {

    @Autowired
    ImGroupDao imGroupDao;
    @Autowired
    UserDao userDao;
    @Autowired
    ImGroupUserDao  imGroupUserDao;
    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        IPage<ImGroupEntity> page = this.page(
                new Query<ImGroupEntity>().getPage(params),
                new QueryWrapper<ImGroupEntity>()
        );

        return new PageUtils(page);
    }

    @Override
    public R check(UserEntity user, ImGroupEntity imGroup) {
        // 群组是否存在
        ImGroupEntity ig = this.baseMapper.selectById(imGroup.getId());
        if (ig==null) {
            return R.error("该群聊不存在或者已被封禁");
        }
        List<ImGroupUserEntity> list = imGroupUserDao.getList(imGroup.getId());
        // 当前用户是否是该群成员
        boolean is = true;
        String fromname = "";
        for(ImGroupUserEntity it : list){
            if(it.getUserId().toString().equals(user.getUserId().toString())){
                fromname = !it.getNickname().equals("")?it.getNickname():(!it.getUsernickname().equals("")?it.getUsernickname():it.getUsername());
                is=false;
                break;
            }
        }
        if(is){
            return R.error("你不是该群成员，没有权限");
        }
        return R.ok();
    }

    @Override
    public List<ImGroupEntity> getList(UserEntity user) {
        return imGroupDao.getList(user);
    }

    @Transactional
    @Override
    public Map<String,Object> create(UserEntity user ,Map<String,String []> map)  throws Exception {
        String [] ids = map.get("ids");
        String name = user.getNickname()==null?user.getUsername():user.getNickname()+",";
        //把自己加进去
        List<String> r = new ArrayList<>();
        for (String str : ids){
            UserEntity u = userDao.selectById(str);
            name += (u.getNickname()==null?u.getUsername():u.getNickname());
            r.add(str);
        }
        r.add(user.getUserId().toString());
        ids = r.toArray(new String[0]);
        //加主表
        ImGroupEntity ig = new ImGroupEntity();
        ig.setUserId(user.getUserId().intValue());
        ig.setAvatar("");
        ig.setName(name);
        this.baseMapper.insert(ig);
        //加字表
        ImGroupUserEntity igu = new ImGroupUserEntity();
        igu.setGroupId(ig.getId());
        igu.setUpdatedAt(new Date());
        igu.setCreatedAt(new Date());
        for (String str : ids){
            igu.setUserId(Integer.parseInt(str));
            imGroupUserDao.insert(igu);
        }
        //
        Message message = new Message();
        message.setId(String.valueOf((new Date()).getTime()));
        message.setFrom_avatar(user.getAvatar());
        message.setFrom_name(!user.getNickname().equals("")?user.getNickname():user.getUsername());
        message.setFrom_id(user.getUserId().toString());
        message.setTo_id(ig.getId().toString());// 接收人/群 id
        message.setTo_name(ig.getName());
        message.setTo_avatar(ig.getAvatar());
        message.setChat_type("group");
        message.setType("system");
        message.setData("创建群聊成功，可以开始聊天啦");
        message.setCreate_time((new Date()).getTime());
        message.setIsremove(0);
        Map<String, Object> mapa = new HashMap<>();
        mapa.put("message",message);

        mapa.put("ids",ids);
        //绑定群
        for (String str : ids){
            ChannelContext cc = WsOnlineContext.getChannelContextByUser(str);
            if(cc!=null && !cc.isClosed){
                Tio.bindGroup(cc,ig.getId().toString());
            }
        }
        //发送信息
        SendInfo sendInfo = new SendInfo();
        sendInfo.setCode(ChatUtils.MSG_MESSAGE);
        sendInfo.setMessage(message);
        WsResponse wsResponse = WsResponse.fromText(new ObjectMapper().writeValueAsString(sendInfo), TioServerConfig.CHARSET);
        ChannelContext cco = WsOnlineContext.getChannelContextByUser(user.getUserId().toString());
        Tio.sendToGroup(cco.groupContext, ig.getId().toString(), wsResponse);
        return mapa;
    }

    @Override
    public R info(UserEntity user ,Integer id) {
        Map<String,Object> map = new HashMap<>();
        // 群组是否存在
        ImGroupEntity imGroup = this.baseMapper.selectById(id);
        if (imGroup==null) {
            return R.error("该群聊不存在或者已被封禁");
        }
        List<ImGroupUserEntity> list = imGroupUserDao.getList(id);
        // 当前用户是否是该群成员
        boolean is = true;
        for(ImGroupUserEntity it : list){
            if(it.getUserId().toString().equals(user.getUserId().toString())){
                is=false;
                break;
            }
        }
        if(is){
            return R.error("你不是该群成员，没有权限");
        }
        map.put("imGroup",imGroup);
        map.put("group_users",list);
        return R.ok(map);
    }

    @Override
    public R update(UserEntity user, ImGroupEntity imGroup) {
        Map<String,Object> map = new HashMap<>();
        // 群组是否存在
        ImGroupEntity ig = this.baseMapper.selectById(imGroup.getId());
        if (ig==null) {
            return R.error("该群聊不存在或者已被封禁");
        }
        List<ImGroupUserEntity> list = imGroupUserDao.getList(imGroup.getId());
        // 当前用户是否是该群成员
        boolean is = true;
        String fromname = "";
        for(ImGroupUserEntity it : list){
            if(it.getUserId().toString().equals(user.getUserId().toString())){
                fromname = !it.getNickname().equals("")?it.getNickname():(!it.getUsernickname().equals("")?it.getUsernickname():it.getUsername());
                is=false;
                break;
            }
        }
        if(is){
            return R.error("你不是该群成员，没有权限");
        }
        // 验证是否是群主
        if (!ig.getUserId().toString().equals(user.getUserId().toString())) {
            return R.error("你不是管理员，没有权限");
        }
        // 修改群名称
        this.baseMapper.updateById(imGroup);
        Message message = new Message();
        message.setId(String.valueOf((new Date()).getTime()));
        message.setFrom_avatar(user.getAvatar());
        message.setFrom_name(fromname);
        message.setFrom_id(user.getUserId().toString());
        message.setTo_id(ig.getId().toString());// 接收人/群 id
        message.setTo_name(imGroup.getName());
        message.setTo_avatar(ig.getAvatar());
        message.setChat_type("group");
        message.setType("system");
        message.setData(fromname + "修改群名称为" + imGroup.getName());
        message.setCreate_time((new Date()).getTime());
        message.setIsremove(0);
        //发送信息
        SendInfo sendInfo = new SendInfo();
        sendInfo.setCode(ChatUtils.MSG_MESSAGE);
        sendInfo.setMessage(message);
        WsResponse wsResponse = null;
        try {
            wsResponse = WsResponse.fromText(new ObjectMapper().writeValueAsString(sendInfo), TioServerConfig.CHARSET);
        } catch (JsonProcessingException e) {
            e.printStackTrace();
        }
        ChannelContext cco = WsOnlineContext.getChannelContextByUser(user.getUserId().toString());
        Tio.sendToGroup(cco.groupContext, ig.getId().toString(), wsResponse);

        map.put("imGroup",imGroup);
        map.put("message",message);
        return R.ok(map);
    }

    @Override
    public R nickname(UserEntity user, ImGroupEntity imGroup) {
        // 群组是否存在
        ImGroupEntity ig = this.baseMapper.selectById(imGroup.getId());
        if (ig==null) {
            return R.error("该群聊不存在或者已被封禁");
        }
        List<ImGroupUserEntity> list = imGroupUserDao.getList(imGroup.getId());
        // 当前用户是否是该群成员
        boolean is = true;
        ImGroupUserEntity u = null;
        for(ImGroupUserEntity it : list){
            if(it.getUserId().toString().equals(user.getUserId().toString())){
                u=it;
                is=false;
                break;
            }
        }
        if(is){
            return R.error("你不是该群成员，没有权限");
        }
        // 修改本群名称
        u.setNickname(imGroup.getNickname());
        imGroupUserDao.updateById(u);
        return R.ok();
    }

    @Override
    public R remark(UserEntity user, ImGroupEntity imGroup) {
        // 群组是否存在
        ImGroupEntity ig = this.baseMapper.selectById(imGroup.getId());
        if (ig==null) {
            return R.error("该群聊不存在或者已被封禁");
        }
        List<ImGroupUserEntity> list = imGroupUserDao.getList(imGroup.getId());
        // 当前用户是否是该群成员
        boolean is = true;
        String fromname = "";
        for(ImGroupUserEntity it : list){
            if(it.getUserId().toString().equals(user.getUserId().toString())){
                fromname = !it.getNickname().equals("")?it.getNickname():(!it.getUsernickname().equals("")?it.getUsernickname():it.getUsername());
                is=false;
                break;
            }
        }
        if(is){
            return R.error("你不是该群成员，没有权限");
        }
        // 验证是否是群主
        if (!ig.getUserId().toString().equals(user.getUserId().toString())) {
            return R.error("你不是管理员，没有权限");
        }
        // 修改公告
        this.baseMapper.updateById(imGroup);
        Message message = new Message();
        message.setId(String.valueOf((new Date()).getTime()));
        message.setFrom_avatar(user.getAvatar());
        message.setFrom_name(fromname);
        message.setFrom_id(user.getUserId().toString());
        message.setTo_id(ig.getId().toString());// 接收人/群 id
        message.setTo_name(ig.getName());
        message.setTo_avatar(ig.getAvatar());
        message.setChat_type("group");
        message.setType("system");
        message.setData("[新公告]" + imGroup.getRemark());
        message.setCreate_time((new Date()).getTime());
        message.setIsremove(0);
        //发送信息
        SendInfo sendInfo = new SendInfo();
        sendInfo.setCode(ChatUtils.MSG_MESSAGE);
        sendInfo.setMessage(message);
        WsResponse wsResponse = null;
        try {
            wsResponse = WsResponse.fromText(new ObjectMapper().writeValueAsString(sendInfo), TioServerConfig.CHARSET);
        } catch (JsonProcessingException e) {
            e.printStackTrace();
        }
        ChannelContext cco = WsOnlineContext.getChannelContextByUser(user.getUserId().toString());
        Tio.sendToGroup(cco.groupContext, ig.getId().toString(), wsResponse);

        return R.ok();
    }

    @Transactional
    @Override
    public R quit(UserEntity user, ImGroupEntity imGroup) {
        // 群组是否存在
        ImGroupEntity ig = this.baseMapper.selectById(imGroup.getId());
        if (ig==null) {
            return R.error("该群聊不存在或者已被封禁");
        }
        List<ImGroupUserEntity> list = imGroupUserDao.getList(imGroup.getId());
        // 当前用户是否是该群成员
        boolean is = true;
        String fromname = "";
        ImGroupUserEntity groupUser = null;
        for(ImGroupUserEntity it : list){
            if(it.getUserId().toString().equals(user.getUserId().toString())){
                groupUser = it;
                fromname = !it.getNickname().equals("")?it.getNickname():(!it.getUsernickname().equals("")?it.getUsernickname():it.getUsername());
                is=false;
                break;
            }
        }
        if(is){
            return R.error("你不是该群成员，没有权限");
        }

        Message message = new Message();
        message.setId(String.valueOf((new Date()).getTime()));
        message.setFrom_avatar(user.getAvatar());
        message.setFrom_name(fromname);
        message.setFrom_id(user.getUserId().toString());
        message.setTo_id(ig.getId().toString());// 接收人/群 id
        message.setTo_name(ig.getName());
        message.setTo_avatar(ig.getAvatar());
        message.setChat_type("group");
        message.setType("system");

        message.setCreate_time((new Date()).getTime());
        message.setIsremove(0);
        // 验证是群主还是成员
        if (!ig.getUserId().toString().equals(user.getUserId().toString())) {
            imGroupUserDao.deleteById(groupUser.getId());
            message.setData(fromname + "退出该群聊");

        }else {
            this.baseMapper.deleteById(ig.getId());
            message.setData(fromname + "该群已被解散");
        }


        //发送信息
        SendInfo sendInfo = new SendInfo();
        sendInfo.setCode(ChatUtils.MSG_MESSAGE);
        sendInfo.setMessage(message);
        WsResponse wsResponse = null;
        try {
            wsResponse = WsResponse.fromText(new ObjectMapper().writeValueAsString(sendInfo), TioServerConfig.CHARSET);
        } catch (JsonProcessingException e) {
            e.printStackTrace();
        }
        ChannelContext cco = WsOnlineContext.getChannelContextByUser(user.getUserId().toString());
        Tio.sendToGroup(cco.groupContext, ig.getId().toString(), wsResponse);
        //解除绑定群组
        Tio.unbindGroup(imGroup.getId().toString(),cco);
        return R.ok();
    }

    @Override
    public R invite(UserEntity user, ImGroupEntity imGroup) {
        // 群组是否存在
        ImGroupEntity ig = this.baseMapper.selectById(imGroup.getId());
        if (ig==null) {
            return R.error("该群聊不存在或者已被封禁");
        }
        List<ImGroupUserEntity> list = imGroupUserDao.getList(imGroup.getId());
        // 当前用户是否是该群成员
        boolean is = true;
        String fromname = "";
        ImGroupUserEntity groupUser = null;
        for(ImGroupUserEntity it : list){
            if(it.getUserId().toString().equals(user.getUserId().toString())){
                groupUser = it;
                fromname = !it.getNickname().equals("")?it.getNickname():(!it.getUsernickname().equals("")?it.getUsernickname():it.getUsername());
                is=false;
                break;
            }
        }
        if(is){
            return R.error("你不是该群成员，没有权限");
        }
        // 对方是否存在
        UserEntity u =userDao.selectOne(new QueryWrapper<UserEntity>().eq("user_id",imGroup.getUserId()).eq("status",0));
        if(u==null){
            return R.error("对方不存在或者已被封禁");
        };
        // 加入该群
        ImGroupUserEntity bean = new ImGroupUserEntity();
        bean.setGroupId(ig.getId());
        bean.setUserId(imGroup.getUserId());
        String invitename = u.getNickname().equals("")?u.getUsername():u.getNickname();
        bean.setNickname(invitename);
        bean.setCreatedAt(new Date());
        bean.setUpdatedAt(new Date());
        imGroupUserDao.insert(bean);
        //绑定群组
        ChannelContext cc = WsOnlineContext.getChannelContextByUser(imGroup.getUserId().toString());
        Tio.bindGroup(cc, ig.getId().toString());


        Message message = new Message();
        message.setId(String.valueOf((new Date()).getTime()));
        message.setFrom_avatar(user.getAvatar());
        message.setFrom_name(fromname);
        message.setFrom_id(user.getUserId().toString());
        message.setTo_id(ig.getId().toString());// 接收人/群 id
        message.setTo_name(ig.getName());
        message.setTo_avatar(ig.getAvatar());
        message.setChat_type("group");
        message.setType("system");
        message.setData(fromname + "邀请"+ invitename+ "加入群聊");
        message.setCreate_time((new Date()).getTime());
        message.setIsremove(0);

        //发送信息
        SendInfo sendInfo = new SendInfo();
        sendInfo.setCode(ChatUtils.MSG_MESSAGE);
        sendInfo.setMessage(message);
        WsResponse wsResponse = null;
        try {
            wsResponse = WsResponse.fromText(new ObjectMapper().writeValueAsString(sendInfo), TioServerConfig.CHARSET);
        } catch (JsonProcessingException e) {
            e.printStackTrace();
        }
        ChannelContext cco = WsOnlineContext.getChannelContextByUser(user.getUserId().toString());

        Tio.sendToGroup(cco.groupContext, ig.getId().toString(), wsResponse);

        return R.ok();
    }

    @Override
    public R kickoff(UserEntity user, ImGroupEntity imGroup) {
        // 群组是否存在
        ImGroupEntity ig = this.baseMapper.selectById(imGroup.getId());
        if (ig==null) {
            return R.error("该群聊不存在或者已被封禁");
        }
        List<ImGroupUserEntity> list = imGroupUserDao.getList(imGroup.getId());
        // 当前用户是否是该群成员
        boolean is = true;
        String fromname = "";
        for(ImGroupUserEntity it : list){
            if(it.getUserId().toString().equals(user.getUserId().toString())){
                fromname = !it.getNickname().equals("")?it.getNickname():(!it.getUsernickname().equals("")?it.getUsernickname():it.getUsername());
                is=false;
                break;
            }
        }
        if(is){
            return R.error("你不是该群成员，没有权限");
        }
        // 验证是否是群主
        if (!ig.getUserId().toString().equals(user.getUserId().toString())) {
            return R.error("你不是管理员，没有权限");
        }
        if(imGroup.getUserId().toString().equals(user.getUserId().toString())){
            return R.error("不能踢自己");
        }
        //对方不是该群成员
        boolean isHave = true;
        String kickname = "";
        ImGroupUserEntity igu = null;
        for(ImGroupUserEntity it : list){
            if(it.getUserId().toString().equals(imGroup.getUserId().toString())){
                igu = it;
                kickname = !it.getNickname().equals("")?it.getNickname():(!it.getUsernickname().equals("")?it.getUsernickname():it.getUsername());
                isHave=false;
                break;
            }
        }
        if(isHave){
            return R.error("对方不是该群成员");
        }
        // 踢出该群
        imGroupUserDao.deleteById(igu);

        Message message = new Message();
        message.setId(String.valueOf((new Date()).getTime()));
        message.setFrom_avatar(user.getAvatar());
        message.setFrom_name(fromname);
        message.setFrom_id(user.getUserId().toString());
        message.setTo_id(ig.getId().toString());// 接收人/群 id
        message.setTo_name(ig.getName());
        message.setTo_avatar(ig.getAvatar());
        message.setChat_type("group");
        message.setType("system");
        message.setData(fromname + "将" + kickname + "移出群聊");
        message.setCreate_time((new Date()).getTime());
        message.setIsremove(0);

        //发送信息
        SendInfo sendInfo = new SendInfo();
        sendInfo.setCode(ChatUtils.MSG_MESSAGE);
        sendInfo.setMessage(message);
        WsResponse wsResponse = null;
        try {
            wsResponse = WsResponse.fromText(new ObjectMapper().writeValueAsString(sendInfo), TioServerConfig.CHARSET);
        } catch (JsonProcessingException e) {
            e.printStackTrace();
        }
        ChannelContext cco = WsOnlineContext.getChannelContextByUser(user.getUserId().toString());
        Tio.sendToGroup(cco.groupContext, ig.getId().toString(), wsResponse);
        //解除绑定群组
        ChannelContext cc = WsOnlineContext.getChannelContextByUser(imGroup.getUserId().toString());
        Tio.unbindGroup(imGroup.getId().toString(),cc);
        return R.ok();
    }


}
